package com.zhouxiaoxuan13.consumer.config;

import feign.Logger;
import feign.Request;
import feign.Retryer;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.github.resilience4j.timelimiter.TimeLimiterConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JCircuitBreakerFactory;
import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JConfigBuilder;
import org.springframework.cloud.client.circuitbreaker.Customizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

/**
 * OpenFeign配置类
 * 配置Feign客户端的超时、重试、日志和熔断器
 */
@Slf4j
@Configuration
public class FeignConfig {

    /**
     * Feign日志级别配置
     * NONE: 不记录任何日志（默认）
     * BASIC: 仅记录请求方法、URL以及响应状态码和执行时间
     * HEADERS: 记录BASIC级别的基础上，记录请求和响应的header
     * FULL: 记录请求和响应的header、body和元数据
     */
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

    /**
     * Feign请求超时配置
     * connectTimeout: 连接超时时间
     * readTimeout: 读取超时时间
     */
    @Bean
    public Request.Options feignRequestOptions() {
        return new Request.Options(
            5000,  // 连接超时时间：5秒
            10000  // 读取超时时间：10秒
        );
    }

    /**
     * Feign重试配置
     * period: 重试间隔时间
     * maxPeriod: 最大重试间隔时间
     * maxAttempts: 最大重试次数
     */
    @Bean
    public Retryer feignRetryer() {
        return new Retryer.Default(
            100,    // 初始重试间隔：100ms
            1000,   // 最大重试间隔：1秒
            3       // 最大重试次数：3次
        );
    }

    /**
     * 熔断器配置
     * 配置Resilience4j熔断器的参数
     */
    @Bean
    public Customizer<Resilience4JCircuitBreakerFactory> defaultCustomizer() {
        return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
            .timeLimiterConfig(TimeLimiterConfig.custom()
                .timeoutDuration(Duration.ofSeconds(10))  // 超时时间：10秒
                .build())
            .circuitBreakerConfig(CircuitBreakerConfig.custom()
                .failureRateThreshold(50)                 // 失败率阈值：50%
                .waitDurationInOpenState(Duration.ofMillis(1000))  // 熔断器打开状态等待时间：1秒
                .slidingWindowSize(10)                    // 滑动窗口大小：10个请求
                .minimumNumberOfCalls(5)                  // 最小调用次数：5次
                .build())
            .build());
    }

    /**
     * 熔断器注册表
     * 用于监控和管理熔断器实例
     */
    @Bean
    public CircuitBreakerRegistry circuitBreakerRegistry() {
        log.info("🔧 创建 CircuitBreakerRegistry Bean");
        return CircuitBreakerRegistry.ofDefaults();
    }
}
